package cn.remex.db.utils.reflect;

import java.util.HashMap;
import java.util.Map;


/**
 * 映射配置类
 *
 * @author HengYang Liu
 */
public class ReflectConfigure {


    private static ReflectContextFactory reflectContextFactory = null;


    public static Map<String, FieldMapper> FieldMapperMap = new HashMap<String, FieldMapper>();
    public static Map<String, CodeMapper> CodeMapperMap = new HashMap<String, CodeMapper>();

    public static Map<String, ReflectContext> ReflectContextMap = new HashMap<String, ReflectContext>();
    final public static ReflectContext NullReflectContext = new ReflectContext();

    private static boolean autoFetchFromPlugin = false;

    /**
     * 用于spring 中配置属性映射
     *
     * @param fieldMapper TODO 怎么配置
     */
    @Deprecated
    public static void setFieldMapper(final FieldMapper fieldMapper) {
        FieldMapperMap.put(ReflectUtil.hashCodeWithOrder(fieldMapper.getLeftClass(), fieldMapper.getRightClass()), fieldMapper);
        Map<String, String> fieldMap = fieldMapper.obtainFieldMap();

        FieldMapper revertFieldMapper = new FieldMapper(fieldMapper.getRightClass(), fieldMapper.getLeftClass()); // 因为反转，所以此行的参数right、left要注意方向
        Map<String, String> revertfieldMap = new HashMap<String, String>();
        for (String field : fieldMap.keySet()) {
            revertfieldMap.put(fieldMap.get(field), field);
        }

        revertFieldMapper.setFieldMap(revertfieldMap);

        FieldMapperMap.put(ReflectUtil.hashCodeWithOrder(fieldMapper.getRightClass(), fieldMapper.getLeftClass()), revertFieldMapper);
    }


    /**
     * 清除映射缓存<br>
     * 1.清除属性映射Map<br>2.清除代码映射Map<br>3.清除反射上下文Map
     */
    public static void clearCache() {
        FieldMapperMap = new HashMap<String, FieldMapper>();
        CodeMapperMap = new HashMap<String, CodeMapper>();
        ReflectContextMap = new HashMap<String, ReflectContext>();
    }

    /**
     * 获取 映射上下文
     *
     * @param target       拷贝的目标对象
     * @param source       拷贝的来源对象
     * @param fieldMapType 属性映射在数据库中type类型
     * @param valueMapType 值映射在数据库中type类型
     * @return ReflectContext 映射上下文
     * TODO
     */
    static ReflectContext obtainReflectContext(Class<?> target, Class<?> source, String fieldMapType, String valueMapType) {
        String hashcode = ReflectUtil.hashCodeWithOrder(target, source, fieldMapType, valueMapType);
        ReflectContext reflectContext = ReflectContextMap.get(hashcode);
        if (reflectContext == null) { // 缓存为空，查询数据库
            if (autoFetchFromPlugin) {
                reflectContext = reflectContextFactory.obtainReflectContext(target, source, fieldMapType, valueMapType);
                ReflectContextMap.put(hashcode, reflectContext);
            } else {
                reflectContext = NullReflectContext;
            }
        }
        return reflectContext;
    }
}
